/*
 * `fmt::Debug` 通常看起来不太简洁，因此自定义输出外观经常是更可取的。需要通过手动
 * 实现`fmt::Display`来做到。`fmt::Display` 采用 {} 标记。
 * 注意：对于`Vec<T>`或其他任意泛型容器，`fmt::Display`都没有实现。因此这些泛型的情况
 * 下要用`fmt::Debug`。对于任何非泛型的容器类型，`fmt::Display`都能实现。
 */

// 导入`fmt`模块，使`fmt::Display`可用
use std::fmt;

// 带有两个数字的结构体。推导出`Debug`，以便与`Display`的输出进行比较
#[derive(Debug)]
struct MinMax(i64, i64);

// 实现`MinMax`的`Display`
impl fmt::Display for MinMax {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // 使用 `self.number`来表示各个数据
        write!(f, "({}, {})", self.0, self.1)
    }
}

// 为了比较，定义一个含有具名字段的结构体
#[derive(Debug)]
struct Point2D {
    x: f64,
    y: f64,
}

// 对`Point2D`实现`Display`
impl fmt::Display for Point2D {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "x: {}, y: {}", self.x, self.y)
    }
}

fn main() {
    let minmax = MinMax(0, 14);

    println!("Compare structures: ");
    println!("Display: {}", minmax);
    println!("Debug: {:?}", minmax);

    let big_range = MinMax(-300, 300);
    let small_range = MinMax(-3, 3);

    println!("The big range is {big} and the small is {small}",
            small = small_range,
            big = big_range,
            );

    let point = Point2D{ x: 3.3, y: 7.2 };
    println!("Compare points: ");
    println!("Display: {}", point);
    println!("Debug: {:?}", point);

    // `{:b}` 需要实现 `fmt::Binary`，由于没实现，以下报错
    //println!("{:b}", point);
}